
#include <QGraphicsLinearLayout>
#include <QLabel>
#include <QAction>

#include "wppostgraphicslistitem.h"
#include "wppostgraphicslist.h"
#include "WPData.h"
#include "BlogView.h"
#include "PopupMenu.h"
#include "wpconfirmdialog.h"

#include "buttongraphicsproxy.h"
#include "ShadowGraphicsItem.h"
#include "ListTitle.h"
#include "utils.h"

WPPostGraphicsList::WPPostGraphicsList(
        const QGraphicsView& aGraphicsView,BlogView* aBlogView, PannableView* aPannableView
    ) : 
		WPGraphicsList(aBlogView, aGraphicsView, aPannableView)
{   
    // TODO find a proper way to align menu icon and text side by side.
    iActionOpen = new QAction(iThemeData.GetContextIcon(ThemeData::EOpen),tr("Open"), this);
    iActionEdit = new QAction(iThemeData.GetContextIcon(ThemeData::EEdit),tr("Edit"), this);
    iActionDelete = new QAction(iThemeData.GetContextIcon(ThemeData::ERemove),tr("Delete"), this);

    connect(iActionOpen, SIGNAL(triggered(bool)), this, SLOT(Open()));
    connect(iActionEdit, SIGNAL(triggered(bool)), this, SLOT(Edit()));
    connect(iActionDelete, SIGNAL(triggered(bool)), this, SLOT(Delete()));

    iNewPostButton = new ButtonGraphicsProxy(tr("Write new post"), this);
    iNewPostButton->button()->setObjectName("newPostButton");
    iNewPostButton->button()->setStyleSheet(iThemeData.iListButtonQss);
    connect(iNewPostButton->button(), SIGNAL(clicked(bool)), aBlogView, SLOT(ShowWriteNewPostView()));

    // labels, not automatically added
    iDraftsLabel = new ListTitle(this, iThemeData);
    iDraftsTopShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Top, this);
    iDraftsBottomShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Bottom, this);
    
    iPostsLabel = new ListTitle(this, iThemeData);
    iPostsTopShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Top, this);
    iPostsBottomShadow = new ShadowGraphicsItem(ShadowGraphicsItem::Bottom, this);
    
    iLayout->addItem(iNewPostButton);
    
    iLayout->addItem(iDraftsLabel);
    iLayout->addItem(iDraftsTopShadow);
    iDraftsLayout = AddLayout();
    iLayout->addItem(iDraftsBottomShadow);
    
    iLayout->addItem(iPostsLabel);
    iLayout->addItem(iPostsTopShadow);
    iPostsLayout = AddLayout();
    iLayout->addItem(iPostsBottomShadow);
    
    UpdateLabels();
}

WPPostGraphicsList::~WPPostGraphicsList()
{
    
}


void WPPostGraphicsList::PopulatePopupMenuForCurrentItem(PopupMenu* aPopupMenu)
{
    aPopupMenu->addAction(iActionOpen);
    aPopupMenu->setActiveAction(iActionOpen);
    aPopupMenu->addAction(iActionEdit);
    aPopupMenu->addAction(iActionDelete);
}

void WPPostGraphicsList::AddPost(WPPost aPost)
{
    QStringList list;

    if (aPost->IsLocal())
        list << "Local draft";

    list << WPNetworkEngine::LocalizedTime(aPost->iDateCreated);

    WPPostGraphicsListItem* item = new WPPostGraphicsListItem(aPost, iBusyIndicator, iThemeData);
    connect(item, SIGNAL(Selected(WPGraphicsListItem*)), this, SLOT(ShowContextMenu(WPGraphicsListItem*)));

    if(aPost->IsDraft()) {
        OrderedInsert(*iDraftsLayout, *item);
    } else {
        OrderedInsert(*iPostsLayout, *item);
    }
}

void WPPostGraphicsList::RemovePost (WPPost aPost)
{
    WPPostGraphicsListItem * item = 0;
        
    item = RemoveFromLayout(*iDraftsLayout, aPost);
    if(!item) { item = RemoveFromLayout(*iPostsLayout, aPost); }
    
    delete item;
    UpdateLabels();
}

void WPPostGraphicsList::Open()
{
    qDebug("WP::WPPostGraphicsList::Open");
    if(CurrentItem())
        emit OpenClicked(CurrentItem()->GetPost());
}

void WPPostGraphicsList::Edit()
{
    qDebug("WP::WPPostGraphicsList::Edit");
    if(CurrentItem())
        emit EditClicked(CurrentItem()->GetPost());
}

void WPPostGraphicsList::Delete()
{
    WP_CONFIRM_AND_RETURN_ON_FALSE(0)

    qDebug("WP::WPPostGraphicsList::Delete");
    if(CurrentItem())
        emit DeleteClicked(CurrentItem()->GetPost());
}

void WPPostGraphicsList::UpdatePostData(const WPDataBlog& aBlog)
{
    if(iCurrentBlog) {
        disconnect(iCurrentBlog, NULL, this, NULL);
    }
    iCurrentBlog = const_cast<WPDataBlog *>(&aBlog);
    
    ClearLayout(*iDraftsLayout);
    ClearLayout(*iPostsLayout);
    
    QListIterator<WPPost> posts(aBlog.GetPosts());
    while (posts.hasNext()) {
        WPPost post = posts.next();
        AddPost(post);
    }
    
    connect(
       &aBlog,  SIGNAL(PostAdded(WPPost)), 
       this,    SLOT(PostAdded(WPPost))
    );
    connect(
       &aBlog,  SIGNAL(PostChanged(WPPost)), 
       this,    SLOT(PostChanged(WPPost))
    );
    connect(
       &aBlog,  SIGNAL(PostRemoved(WPPost)), 
       this,    SLOT(PostRemoved(WPPost))
    );
       
    UpdateLabels();
}

void WPPostGraphicsList::PostChanged(WPPost aPost)
{
    qDebug("WPPostGraphicsList::PostChanged");

    // cycle
    RemovePost(aPost);
    AddPost(aPost);
    
    UpdateLabels();
}

void WPPostGraphicsList::PostRemoved(WPPost aPost)
{
    qDebug("WPPostGraphicsList::PostRemoved");

    RemovePost(aPost);
    UpdateLabels();
}

void WPPostGraphicsList::PostAdded(WPPost aPost)
{
    qDebug("WPPostGraphicsList::PostAdded");

    AddPost(aPost);
    UpdateLabels();
}

void WPPostGraphicsList::UpdateLabels()
{
    int drafts = iDraftsLayout->count();
    SubLayout draftsLayout(iDraftsLabel, iDraftsTopShadow, iDraftsLayout, iDraftsBottomShadow);
    if (drafts) {
        iDraftsLabel->setText(tr("Drafts") + " (" + QString::number(drafts) + ')');
        ShowSubLayout(draftsLayout, iNewPostButton);
    } else {
        HideSubLayout(draftsLayout);
    }

    int posts = iPostsLayout->count();
    SubLayout postsLayout(iPostsLabel, iPostsTopShadow, iPostsLayout, iPostsBottomShadow);
    if (posts) {
        iPostsLabel->setText(tr("Posts") + " (" + QString::number(posts) + ')');
        LayoutItemList insertPoints;
        insertPoints << iDraftsBottomShadow << iNewPostButton;
        ShowSubLayout(postsLayout, insertPoints);
    } else {
        HideSubLayout(postsLayout);
    }
}

void WPPostGraphicsList::OrderedInsert(QGraphicsLinearLayout & layout, WPPostGraphicsListItem & item)
{
    int i;
    for(i = 0; i < layout.count(); ++i) {
        WPPostGraphicsListItem * listItem = LayoutToListItem(layout.itemAt(i));
        if(*listItem < item) { break; }
    }
    layout.insertItem(i, &item);
}

WPPostGraphicsListItem * WPPostGraphicsList::RemoveFromLayout(QGraphicsLinearLayout & layout, WPPost post)
{
    for(int i = 0; i < layout.count(); ++i) {
        WPPostGraphicsListItem * item = LayoutToListItem(layout.itemAt(i));
        if(item->GetPost() == post) {
            IteratorGuard itGuard(*this, item);
            layout.removeAt(i);
            return item;
        }
    }
    return 0;
}

bool WPPostGraphicsList::IsFocusable(QGraphicsLayoutItem * item)
{
    QGraphicsItem * gItem = item->graphicsItem();
    return (WPGraphicsList::IsListItem(gItem) || gItem == iNewPostButton); 
}

